home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-13 | 49.2 KB | 1,457 lines | [TEXT/MPS ] |
- (******************************************************************************
- *
- * Apple Macintosh Developer Technical Support
- *
- * Code for the dialog routines
- *
- * Program: Sample 3.0
- * FILE: SampleDialog.inc1.p - Pascal implementation
- *
- * by: Matt Deatherage
- *
- * Copyright © 1988-1993 Apple Computer, Inc.
- * All rights reserved.
- *
- *******************************************************************************
-
- (*******************************************************************************
- *
- * Types
- *
- * PopUpRecord is a record we use to hold the items necessary to define a pop-up
- * menu -- the currently chosen item number and a Handle to the actual menu
- *
- *******************************************************************************)
-
- TYPE
-
- PopUpRecord = RECORD
- chosenItem: INTEGER;
- menuHandle: MenuHandle;
- END;
-
- (*******************************************************************************
- * Private global variables maintained by this unit
- *******************************************************************************)
-
- VAR
-
- { currentCircle is a global variable that holds a circle record,
- and it's this record that we modify. When we initialize, we
- copy the circle we're passed into this variable, and we copy
- it back when we close the dialog if the user didn't cancel. }
-
- currentCircle: CircleRec; { the circle we're modifying }
- fontPopUpRecord, { record for the font pop-up }
- sizePopUpRecord: PopUpRecord; { record for the size pop-up }
-
- oldCircleHeight: LONGINT; { for estimating maximum point size }
-
- PROCEDURE DoEvent(theEvent: EventRecord);
- EXTERNAL; { in Sample.p; used to handle updates }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: DrawPopUpItem
- *
- * This routine takes an item number and draws the "unpopped" state of the
- * pop-up menu user item, including title, drop shadow and down-pointing
- * triangle. This does not use the pop-up menu CDEF because we have to run
- * under System 6 as well. Otherwise we'd make this a lot easier and use
- * the CDEF.
- *
- * The guidelines for the rectangle, down arrow and drop shadow are taken
- * from Human Interface Note #9, which was later folded into Inside Macintosh
- * Volume VI and Macintosh Human Interface Guidelines. The down arrow is 'SICN'
- * resource #128, and we assume this SICN fits between the framed areas at the
- * right edge of the rectangle we draw. in other words, if the rectangle is
- * 19 pixels tall, there will be one line of frame above the SICN, one line
- * of frame below the SICN and one line of drop shadow below that. The arrow
- * is at the left edge of the SICN and the SICN is drawn 18 pixels to the right
- * of the edge of the item rectangle. We create a small BitMap and use
- * CopyBits to draw the triangle.
- *
- * That note also shows a text baseline of 13 pixels below the top of the
- * item rectangle, so that's what we use as well for text drawing. Before
- * drawing the actual string, we use MeasureText and walk through possible
- * string widths, looking to shorten the item string and append the "…"
- * character to a truncated copy of the string if it's too long to fit in the
- * item box. The item box is the same width as the menu, per Macintosh
- * Human Interface Guidelines, even though that always means the longest
- * item will be truncated in the unpopped state.
- *
- * This isn't as international-friendly as it ought to be; the "…" character
- * should really come from a string resource so it can be changed for character
- * sets that don't have it as the same ASCII value.
- *
- ******************************************************************************)
-
- PROCEDURE DrawPopUpItem(theWindow: WindowPtr; itemNo: INTEGER);
-
- VAR
- ourItemType: INTEGER; { itemType returned by GetDItem }
- ourItem: Handle; { item returned by GetDItem }
- ourItemBox: Rect; { itemBox returned by GetDItem }
- popUpFrameRect: Rect; { frame rectangle for pop-up }
- iconHandle: Handle; { Handle to triangle SICN }
- iconBitMap: BitMap; { BitMap for triangle SICN }
- iconRect: Rect; { rectangle for drawing triangle }
- ourPopUpRecord: PopUpRecord; { the pop-up to draw }
- titleString: Str255; { item chosen currently in pop-up }
- charWidths: ARRAY [0..255] OF INTEGER; { widths of characters to use }
- ellipsisWidth, { width of the "…" character }
- titleWidth, { width of the chosen item string }
- count, { loop variable counter }
- truncatedCount: INTEGER; { count of characters such that
- the string width is less than or
- equal to the available width for
- the title }
-
- BEGIN
-
- { Get the item information for the requested dialog item }
-
- GetDItem(DialogPtr(theWindow), itemNo, ourItemType, ourItem, ourItemBox);
-
- { Draw the drop shadow }
-
- MoveTo(ourItemBox.right - 1, ourItemBox.top + 2);
- lineTo(ourItemBox.right - 1, ourItemBox.bottom);
- lineTo(ourItemBox.left + 2, ourItemBox.bottom);
-
- { frame the pop-up's rectangle }
-
- popUpFrameRect := ourItemBox;
- popUpFrameRect.right := popUpFrameRect.right - 1;
- FrameRect(popUpFrameRect);
- InsetRect(popUpFrameRect, 1, 1);
- EraseRect(popUpFrameRect);
-
- { construct the BitMap for the triangle and draw it }
-
- iconHandle := GetResource('SICN', rPopDownArrowID);
- IF ResError = noErr THEN { don't draw the arrow if the resource call fails }
- BEGIN
- HLock(iconHandle);
- WITH iconBitMap DO
- BEGIN
- { small icons are 16 pixels by 16 pixels -- 2 bytes wide
- by 16 tall }
- baseAddr := iconHandle^; rowBytes := 2;
- SetRect(bounds, 0, 0, 15, 15);
- END; { with iconBitMap do }
- SetRect(iconRect, ourItemBox.right - 17, ourItemBox.top + 1,
- ourItemBox.right - 2, ourItemBox.bottom - 2);
- CopyBits(iconBitMap, GrafPtr(theWindow)^.portBits,
- iconBitMap.bounds, iconRect, srcCopy, NIL);
- HUnlock(iconHandle);
- ReleaseResource(iconHandle);
- END; { if ResError = noErr }
-
- { get the right pop-up record }
-
- IF itemNo = fontPopUp THEN
- ourPopUpRecord := fontPopUpRecord
- ELSE
- ourPopUpRecord := sizePopUpRecord;
-
- { get the string for the chosen item and prepare to draw it }
-
- GetItem(ourPopUpRecord.menuHandle, ourPopUpRecord.chosenItem, titleString);
- MoveTo(ourItemBox.left + 13, ourItemBox.top + 13);
-
- { Now adjust the string to be truncated if necessary to fit in the box }
-
- titleWidth := (ourItemBox.right - 17) - (ourItemBox.left + 13);
- IF StringWidth(titleString) > titleWidth THEN
- BEGIN
- MeasureText(length(titleString), @titleString, @charWidths);
- ellipsisWidth := CharWidth('…');
- truncatedCount := length(titleString);
- FOR count := 1 TO length(titleString) DO
- IF charWidths[count] + ellipsisWidth < titleWidth THEN
- truncatedCount := count;
- titleString := concat(copy(titleString, 1, truncatedCount), '…');
- END;
-
- DrawString(titleString); { yeah, sure, NOW it's easy... }
-
- END; { DrawPopUpItem }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: DrawCircleItem
- *
- * This routine draws the userItem with one of our traffic lights in it.
- * It sets up the light record to show it on and active, but not printing
- * for the global variable currentCircle, and then calls DrawLight to draw it.
- *
- ******************************************************************************)
-
- PROCEDURE DrawCircleItem(theWindow: WindowPtr; itemNo: INTEGER);
-
- VAR
- myLight: LightConditions; { defines a circle and its state }
-
- BEGIN
- WITH myLight DO
- BEGIN
- itsOn := TRUE; { lit and colored }
- itsActive := TRUE; { active so it draws }
- arePrinting := FALSE; { but we're not printing }
- theCircle := @currentCircle; { and this is the circle to draw }
- END;
- DrawLight(myLight);
- END; { DrawCircleItem }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: DrawDefaultItem
- *
- * This is a standard routine that frames the default item (assumed to be
- * item #1) with a round Rect frame 3 pixels wide, as described in Inside
- * Macintosh Volume I.
- *
- ******************************************************************************)
-
- PROCEDURE DrawDefaultItem(theWindow: WindowPtr; itemNo: INTEGER);
-
- VAR
- ourItemType: INTEGER; { these are returned by GetDItem }
- ourItem: Handle;
- ourItemBox: Rect;
-
- BEGIN
-
- { Get the first item and prepare for framing }
-
- GetDItem(DialogPtr(theWindow), 1, ourItemType, ourItem, ourItemBox);
- ForeColor(blackColor); { frame in black, please }
- PenSize(3, 3); { the frame is 3 pixels wide }
- InsetRect(ourItemBox, -4, -4); { Move out by four pixels each way }
- FrameRoundRect(ourItemBox, 16, 16); { frame with radius of 16 pixels }
- PenNormal; { restore pen to normalcy }
- END; { DrawDefaultItem }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: DestroyCircleDialog
- *
- * This routine is the destructor -- it tears down anything built up by
- * InitializeCircleDialog (also in this unit). Right now, that's just the
- * two pop-up menus, which must be deleted and their resources released.
- *
- ******************************************************************************)
-
- PROCEDURE DestroyCircleDialog;
-
- BEGIN
-
- DeleteMenu(mFonts); { kill the menu }
- ReleaseResource(Handle(fontPopUpRecord.menuHandle)); { reclaim the space }
- DeleteMenu(mSize); { kill the menu }
- ReleaseResource(Handle(sizePopUpRecord.menuHandle)); { reclaim the space }
-
- END; { DestroyCircleDialog }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: FindItemInMenu
- *
- * This routine takes a MenuHandle and a string and finds a menu item with
- * the same string, returning the number of it (or zero if there is none).
- *
- ******************************************************************************)
-
- FUNCTION FindItemInMenu(theMenu: MenuHandle; theItem: Str255): INTEGER;
-
- VAR
- counter: INTEGER; { loop variable }
- numItems: INTEGER; { number of items in menu }
- testString: Str255; { holds menu items to test }
-
- BEGIN
- FindItemInMenu := 0; { initialize this to no item found }
- numItems := CountMItems(theMenu); { only call CountMItems once, here }
- FOR counter := 1 TO numItems DO
- BEGIN
- GetItem(theMenu, counter, testString);
- IF testString = theItem THEN
- FindItemInMenu := counter;
- END; { for counter do }
- END; { FindItemInMenu }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: SetItemEnable
- *
- * SetItemEnable makes a given dialog item enabled or disabled, depending on
- * the input value of enableIt.
- *
- ******************************************************************************)
-
- PROCEDURE SetItemEnable(theDialog: DialogPtr; itemNo: INTEGER;
- enableIt: BOOLEAN);
-
- VAR
- ourItemType: INTEGER; { these are returned from GetDItem }
- ourItem: Handle;
- ourItemBox: Rect;
-
- BEGIN
- GetDItem(theDialog, itemNo, ourItemType, ourItem, ourItemBox);
- IF enableIt THEN
- SetDItem(theDialog, itemNo, BAND(ourItemType, -1 - itemDisable),
- ourItem, ourItemBox) { enable the item }
- ELSE
- SetDItem(theDialog, itemNo, BOR(ourItemType, itemDisable), ourItem,
- ourItemBox); { disable the item }
- END; { SetItemEnable }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: GetCheckBoxItemValue
- *
- * This routine takes a DialogPtr and an item number for a checkbox item,
- * and returns TRUE if the box is checked and FALSE if it's not.
- *
- * You're on your own if you pass the item number of a non-checkbox item.
- *
- ******************************************************************************)
-
- FUNCTION GetCheckBoxItemValue(theDialog: DialogPtr; itemNo: INTEGER): BOOLEAN;
-
- VAR
- ourItemType, theValue: INTEGER; { these are returned by GetDItem }
- ourItem: Handle;
- ourItemBox: Rect;
-
- BEGIN
- GetDItem(theDialog, itemNo, ourItemType, ourItem, ourItemBox);
- theValue := GetCtlValue(ControlHandle(ourItem));
- GetCheckBoxItemValue := (theValue <> 0); { if the value is zero, the
- box is not checked }
- END; { GetCheckBoxItemValue }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: SetCheckBoxItemValue
- *
- * SetCheckBoxItemValue takes a BOOLEAN parameter that's TRUE if the box
- * should be checked. It returns a BOOLEAN that's TRUE if the value changed
- * over the previous one.
- *
- * You're on your own if you pass the item number of a non-checkbox item.
- *
- ******************************************************************************)
-
- FUNCTION SetCheckBoxItemValue(theDialog: DialogPtr; itemNo: INTEGER;
- markIt: BOOLEAN): BOOLEAN;
-
- VAR
- ourItemType, { returned by GetDItem }
- theValue: INTEGER; { the existing checkbox value }
- ourItem: Handle; { returned by GetDItem }
- ourItemBox: Rect; { returned by GetDItem }
- wasItChecked: BOOLEAN; { the former state of the checkbox }
-
- BEGIN
- GetDItem(theDialog, itemNo, ourItemType, ourItem, ourItemBox);
- theValue := GetCtlValue(ControlHandle(ourItem));
-
- wasItChecked := (theValue = 1); { while the box will be checked with
- any non-zero value, we only set
- checkbox items to 1 to check them }
- IF markIt THEN
- theValue := 1
- ELSE
- theValue := 0;
- SetCtlValue(ControlHandle(ourItem), theValue);
- SetCheckBoxItemValue := (markIt <> wasItChecked);
- END; { SetCheckBoxItemValue }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: TwiddleCheckBoxItem
- *
- * This routine toggles the state of a checkbox item.
- *
- * You're on your own if you pass the item number of a non-checkbox item.
- *
- ******************************************************************************)
-
- PROCEDURE TwiddleCheckBoxItem(theDialog: DialogPtr; itemNo: INTEGER);
-
- VAR
- ourItemType: INTEGER; { these are returned by GetDItem }
- ourItem: Handle;
- ourItemBox: Rect;
-
- BEGIN
- GetDItem(theDialog, itemNo, ourItemType, ourItem, ourItemBox);
- SetCtlValue(ControlHandle(ourItem), BitXor(GetCtlValue(
- ControlHandle(ourItem)), 1));
-
- END; { TwiddleCheckBoxItem }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: BlinkButtonItem
- *
- * This routine highlights and unhighlights a simple button item, to simulate
- * it being clicked on when you press a key equivalent for it.
- *
- * You're on your own if you pass the item number of a non-button item.
- *
- ******************************************************************************)
-
- PROCEDURE BlinkButtonItem(theDialog: DialogPtr; itemNo: INTEGER);
-
- VAR
- ourItemType: INTEGER; { returned by GetDItem }
- ourItem: Handle; { returned by GetDItem }
- ourItemBox: Rect; { returned by GetDItem }
- theEndingTick: LONGINT; { the TickCount after we blink }
-
- BEGIN
- GetDItem(theDialog, itemNo, ourItemType, ourItem, ourItemBox);
- HiliteControl(ControlHandle(ourItem), inButton); { highlight }
- Delay(8, theEndingTick); { wait eight ticks }
- HiliteControl(ControlHandle(ourItem), 0); { unhighlight }
-
- END;
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: StyleToCheckBoxItems
- *
- * StyleToCheckBoxItems takes a QuickDraw text Style (really an INTEGER) and a
- * starting checkbox dialog item number. It requires eight checkbox items,
- * all numbered consecutively starting with the passed item number in the order
- * bold, italic, underline, outline, shadow, condensed, extended, plain. It
- * sets those checkboxes based on the Style record passed to it. It
- * returns TRUE if any values changed.
- *
- * The Plain box is automatically checked if no other styles are checked,
- * and cleared if any other styles are checked. Technically, I suppose
- * applying both condensed and extended is "plain," but we don't check for
- * that.
- *
- * This routine goes a bit out of the way to deal with Pascal's strict type
- * checking. stylePtr is a Ptr and not an IntegerPtr because if it's
- * an IntegerPtr, the compiler tries to read a two-byte value at an odd
- * address because it knows a Style is only one-byte long and says the address
- * is an odd value. This causes crashes on 68000 machines.
- *
- ******************************************************************************)
-
-
- FUNCTION StyleToCheckBoxItems(theStyle: Style; startingItem: INTEGER;
- theDialog: DialogPtr): BOOLEAN;
-
- VAR
- counter, { loop variable for counting }
- ourIntStyle: INTEGER; { Style as an INTEGER, not record }
- stylePtr: Ptr; { Pointer to make above variable }
- markIt, { TRUE if a box should be checked }
- plain, { TRUE if this is really plain }
- anyChanges: BOOLEAN; { TRUE if any boxes changed states }
-
- BEGIN
-
- stylePtr := @theStyle; { we can assign this as a pointer }
- ourIntStyle := stylePtr^; { dereference it }
- plain := TRUE; { assume this is the plain style }
- anyChanges := FALSE; { assume we won't make changes }
- FOR counter := 0 TO 6 DO
- BEGIN
- IF BTST(ourIntStyle, counter) THEN { if the bit is set then }
- BEGIN
- plain := FALSE; { it's not plain, and }
- markIt := TRUE; { it needs to be marked }
- END
- ELSE
- markIt := FALSE; { it should be cleared }
-
- { set the box and record any changes in our variable }
-
- anyChanges := (anyChanges OR SetCheckBoxItemValue(theDialog,
- startingItem + counter, markIt));
- END; { for counter do }
-
- { here we're done with markIt, so we use it as an "ignore" variable.
- We check the "Plain" box if no other boxes are set, and we disable
- the item if we check it so people can't uncheck it. }
-
- markIt := SetCheckBoxItemValue(theDialog, startingItem + 7, plain);
- SetItemEnable(theDialog, plainBox, NOT plain);
-
- StyleToCheckBoxItems := anyChanges;
-
- END; { StyleToCheckBoxItems }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: CheckBoxItemsToStyle
- *
- * CheckBoxItemsToStyle takes a starting checkbox dialog item and a number
- * and returns a QuickDraw text Style which is really an INTEGER but it's a
- * structure as far as Pascal is concerned. It requires eight checkbox
- * items, all numbered consecutively starting with the passed item number in
- * the order bold, italic, underline, outline, shadow, condensed, extended,
- * plain. It sets those bits in the Style record based on the checkbox
- * settings. It does not return a BOOLEAN value, unlike
- * StyleToCheckBoxItems, because we can just avoid calling it unless we
- * twiddle a checkbox item.
- *
- * The lastHitBox parameter tells us which checkbox was clicked on last.
- * We only call this when we click on a checkbox to update the style in
- * the circle record, and if we don't special-case checking on the plain
- * box, we won't clear the other boxes and bits in the Style record.
- *
- ******************************************************************************)
-
- PROCEDURE CheckBoxItemsToStyle(VAR theStyle: Style; startingItem: INTEGER;
- theDialog: DialogPtr; lastHitBox: INTEGER);
-
- VAR
- counter, { loop variable }
- ourShortStyle: INTEGER; { necessary to cast a record }
- ourLongStyle: LONGINT; { where we build the Style word }
- stylePtr: IntegerPtr; { necessary to cast the record }
- ignore, { throw-away variable }
- Plain: BOOLEAN; { TRUE if the style is Plain }
-
- BEGIN
-
- ourLongStyle := 0; { start out with the plain style }
- Plain := TRUE;
-
- IF lastHitBox = startingItem + 7 THEN { we just hit the plain box -- either
- do nothing or make everything plain}
- BEGIN
- IF GetCheckBoxItemValue(theDialog, lastHitBox) THEN
- { if Plain is checked now, set everything else FALSE }
- FOR counter := 0 TO 6 DO
- ignore := SetCheckBoxItemValue(theDialog, startingItem +
- counter, FALSE)
- END
- ELSE
- BEGIN
- FOR counter := 0 TO 6 DO
- IF GetCheckBoxItemValue(theDialog, counter + startingItem) THEN
- BEGIN
- BSET(ourLongStyle, counter); { set bits for checked }
- Plain := FALSE; { boxes and note not Plain }
- END;
-
- { Now, only after we know the new style, can we safely set/reset boxes based
- on the "plain" choice. We set the "Plain" box (startingItem + 7) to the
- same value we have in our plain variable. }
-
- ignore := SetCheckBoxItemValue(theDialog, startingItem + 7, plain);
-
- END;
-
- ourLongStyle := BSL(ourLongStyle, 8); { shift it left by eight bits to Move
- it into the right byte of the
- INTEGER }
- ourShortStyle := ourLongStyle; { make it an INTEGER, so we can }
- stylePtr := @theStyle; { cast it to a dereferenced }
- stylePtr^ := ourShortStyle; { IntegerPtr here }
-
- END; { CheckBoxItemsToStyle }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: AdjustSizeMenu
- *
- * AdjustSizeMenu takes a PopUpRecord and a dialog item number. It extracts
- * the number from the dialog item and marks the menu item in the pop-up with
- * that string. If there is no such item, one is created at the top and a
- * dividing line placed underneath it. The item number is then filled with
- * the chosen item. We also take a font ID number so we can outline any
- * additions to the size menu if they are, in fact, "real" fonts.
- *
- * textItemNo is the item of the type-in text size item. currentSize and
- * currentFont are the size and font to set things based on. If currentSize
- * is zero, we use the value in the type-in text size item to set the size.
- *
- * This function makes the menu presentable, so we never have to do anything
- * to it until we're ready to pop it up, and this procedure does everything
- * we need to fix that.
- *
- ******************************************************************************)
-
- PROCEDURE AdjustSizeMenu(theDialog: DialogPtr; VAR sizeMenu: PopUpRecord;
- textItemNo, currentSize, currentFont: INTEGER);
-
- VAR
- ourItemType, { returned by GetDItem }
- sizePositionInMenu, { position of our size in the menu }
- startingSizeItem, { where to start looking for the size }
- menuWalker, { count loop variable }
- theSize, { the size we're looking for }
- theFontNum: INTEGER; { the font family number in use }
- textItemHandle: Handle; { Handle to the type-in size item }
- ourItemBox: Rect; { returned by GetDItem }
- dividerExists: BOOLEAN; { TRUE if there's a divider in the size
- menu (meaning there's a custom size }
- theSizeText, { the text in the type-in size item }
- tempText: Str255; { temporary string holding variable }
- theStyle: Style; { to set the style of the menu items }
- theBigSize, { a LONGINT to pass to StringToNum }
- thisItemSize: LONGINT; { a LONGINT for the size of each item }
-
- BEGIN
-
- { First, get the type-in text item's information }
-
- GetDItem(theDialog, textItemNo, ourItemType, textItemHandle, ourItemBox);
- GetIText(textItemHandle, theSizeText); { then get the text of the size }
-
- { If we're passed zero, get the text from the type-in size item }
-
- IF currentSize <> 0 THEN
- BEGIN
- theSize := currentSize;
- NumToString(theSize, theSizeText);
- END
- ELSE
- BEGIN
- StringToNum(theSizeText, theBigSize);
- theSize := theBigSize;
- END;
-
- { We already have a custom size in the menu if the second item is '-',
- which is a dividing line }
-
- GetItem(sizeMenu.menuHandle, 2, tempText);
- dividerExists := (tempText = '-');
-
- { First, if there's a divider, remove it and the old custom size. }
-
- IF dividerExists THEN
- BEGIN
- DelMenuItem(sizeMenu.menuHandle, 1); { kill old custom size, bump
- divider up to #1 }
- DelMenuItem(sizeMenu.menuHandle, 1); { kill old divider }
- END;
-
- { Now that we have the number and the String representing it, we can find
- it in the menu, hopefully }
-
- sizePositionInMenu := FindItemInMenu(sizeMenu.menuHandle, theSizeText);
- startingSizeItem := 1; { there's no custom size right now }
-
- { If the item is in the menu, we're fine. If it's not, we need to
- add a dividing line and a custom size item -- unless the size
- is zero (maybe an empty editText field), in which case we just
- present the standard menu. }
-
- IF ((sizePositionInMenu = 0) AND (theSize <> 0)) THEN
- BEGIN { add it! }
- InsMenuItem(sizeMenu.menuHandle, '-', 0);
- InsMenuItem(sizeMenu.menuHandle, theSizeText, 0);
-
- { If we didn't find the size in the old menu, the size we want to
- use is now item #1. outline it as appropriate, and set the loop
- counter for the rest of the menu to start at item #3. }
-
- IF RealFont(currentFont, theSize) THEN
- theStyle := [outline]
- ELSE
- theStyle := []; { set the outline Status appropriately }
- SetItemStyle(sizeMenu.menuHandle, 1, theStyle);
- startingSizeItem := 3;
- SetItemMark(sizeMenu.menuHandle, 1, char(checkMark));
- sizeMenu.chosenItem := 1;
- END;
-
- { now, walk the menu and set all marks and outline statuses the right way }
-
- FOR menuWalker := startingSizeItem TO CountMItems(sizeMenu.menuHandle) DO
- BEGIN
- GetItem(sizeMenu.menuHandle, menuWalker, tempText);
- StringToNum(tempText, thisItemSize);
- IF RealFont(currentFont, thisItemSize) THEN
- theStyle := [outline]
- ELSE
- theStyle := [];
- SetItemStyle(sizeMenu.menuHandle, menuWalker, theStyle);
-
- IF (menuWalker = sizePositionInMenu) THEN
- BEGIN
- SetItemMark(sizeMenu.menuHandle, menuWalker,
- char(checkMark));
- sizeMenu.chosenItem := menuWalker;
- END
- ELSE
- SetItemMark(sizeMenu.menuHandle, menuWalker, char(noMark));
-
- END; { menu walking loop }
-
- SetIText(textItemHandle, theSizeText); { stuff the type-in item with
- the correct text value }
- SelIText(theDialog, textItemNo, 0, 32767); { and select it }
-
- END; { AdjustSizeMenu }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: MakeDialogCurrent
- *
- * This routine sets up the dialog items based on the currentCircle
- * global record, as a way of updating the dialog to reflect the circle
- * before making it visible for the first time (or whenever it needs a
- * global update, though we only use it in InitializeCircleDialog).
- *
- ******************************************************************************)
-
- PROCEDURE MakeDialogCurrent(theDialog: DialogPtr);
-
- VAR
- ourItemType: INTEGER; { returned by GetDItem }
- ourItem: Handle; { returned by GetDItem }
- ourItemBox: Rect; { returned by GetDItem }
- dialogChanged: BOOLEAN; { returned by StyleToCheckBoxItems }
- sizeText: Str255; { text of size editText item }
-
- BEGIN
-
- { Set up the font menu }
-
- fontPopUpRecord.chosenItem := FindItemInMenu(fontPopUpRecord.menuHandle,
- currentCircle.circleFont);
-
- { Set up the style checkboxes }
-
- dialogChanged := StyleToCheckBoxItems(currentCircle.circleFace, boldBox,
- theDialog);
-
- { Set up the size edit text. Get the size editText item, then get the
- currently selected size edit text item string and copy it into the
- type-in item. }
-
- GetDItem(theDialog, sizeEditText, ourItemType, ourItem, ourItemBox);
- GetItem(sizePopUpRecord.menuHandle, sizePopUpRecord.chosenItem, sizeText);
- SetIText(ourItem, sizeText);
- SelIText(theDialog, sizeEditText, 0, 32767);
-
- { Set up the title text }
-
- GetDItem(theDialog, textEditText, ourItemType, ourItem, ourItemBox);
- SetIText(ourItem, currentCircle.circleText);
-
- END; { MakeDialogCurrent }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: SampleFilterProc
- *
- * We pass SampleFilterProc to ModalDialog for the "Modify Circles" dialog.
- * It filters events and items hit in two ways.
- *
- * First, we filter on events. If it's a keyDown or autoKey event, we check
- * to see if it's an "accept" the dialog key, or a "cancel" key, and blink
- * the appropriate buttons and change the items hit. If we're in the size
- * editText field (noted by looking at the editField field in the dialog
- * record), we reject any keys that aren't digits, command keys or editing
- * keys. Per Inside Macintosh: Macintosh Toolbox Essentials, we pass
- * update and activate events for windows other than the dialog through to
- * our main event handling code, restoring the GrafPort to the dialog when done.
- *
- * Next, we filter on items hit. If we get hits on the fontTitle or fontPopUp,
- * we pop up the font menu and handle any changes made, and the same for the
- * size menu. If it's in the size editText field, we check the new number
- * entered to make sure it's a legal value for the circle sizes we have
- * and alert the user if it's not. If we get hits on the circle title
- * editText item, we update the circle item to reflect the new text.
- *
- * We also monitor all of this to see if any of it changes the circle in the
- * dialog. If it does, we invalidate the circle so it will redraw.
- *
- ******************************************************************************)
-
- FUNCTION SampleFilterProc(theDialog: DialogPtr; VAR theEvent: EventRecord;
- VAR itemHit: INTEGER): BOOLEAN;
-
- VAR
- ourItemType, { returned by GetDItem }
- temp, { used for temporary storage }
- theFlags: INTEGER; { results of ClassifyKey }
- ourItem: Handle; { returned by GetDItem }
- popUpTitleRect, { rectangle of pop-up's title item }
- ourItemBox: Rect; { returned by GetDItem }
- itemChosen, { result of PopUpMenuSelect }
- tempLong: LONGINT; { temporary four-byte storage }
- dialogChanged: BOOLEAN; { TRUE if anything changed }
- tempPoint: Point; { starting Point for PopUpMenuSelect }
- maxRectString, { string holding rectangle size }
- maxPointString, { string holding maximum Point size }
- tempString: Str255; { temporary string storage }
-
- BEGIN
- SampleFilterProc := FALSE; { by default, we didn't handle event }
- dialogChanged := FALSE; { by default, nothing changed }
-
- { First, filter on what kind of event we got. Classify it and act based
- on what kind of key we got, or pass update/activate events for windows
- other than the dialog through to the main event handler. }
-
- CASE theEvent.what OF
-
- keyDown, autoKey:
- BEGIN
- theFlags := ClassifyKey(@theEvent);
- IF (BAND(theFlags, kCancelKey) <> 0) THEN
- BEGIN
- itemHit := cancel;
- BlinkButtonItem(theDialog, cancel);
- SampleFilterProc := TRUE;
- END
- ELSE IF (BAND(theFlags, kAcceptKey) <> 0) THEN
- BEGIN
- itemHit := ok;
- BlinkButtonItem(theDialog, ok);
- SampleFilterProc := TRUE;
- END
- ELSE IF (DialogPeek(theDialog)^.editField + 1 =
- sizeEditText) THEN
- IF BAND(theFlags, kDigitKey + kCommandKey + kEditKey) =
- 0 THEN
- BEGIN
- SampleFilterProc := TRUE;
- SysBeep(5); { beep to indicate there's an INVALID
- entry }
- END;
- END;
-
- updateEvt, activateEvt:
- IF (WindowPtr(theEvent.message) <> theDialog) THEN
- BEGIN
- DoEvent(theEvent); { call main event handler }
- SetPort(theDialog); { and set the port back }
- END;
- OTHERWISE; { prevents undefined case errors }
- END;
-
- { Next, filter on what item got hit. }
-
- CASE itemHit OF
-
- fontTitle, fontPopUp:
- BEGIN
-
- { If we hit either the fontTitle or fontPopUp, invert the
- title rectangle, track the menu with PopUpMenuSelect and
- update the pop-up and the circle if there was a change }
-
- GetDItem(theDialog, fontTitle, ourItemType, ourItem,
- popUpTitleRect);
- InvertRect(popUpTitleRect);
-
- { Pop up the menu at the upper left point of the item
- box, offset by one both down and to the left so the
- text will draw in the menu where it is in the item }
-
- GetDItem(theDialog, fontPopUp, ourItemType, ourItem,
- ourItemBox);
- tempPoint := ourItemBox.topLeft;
- tempPoint.h := tempPoint.h - 1;
- tempPoint.v := tempPoint.v + 1;
- LocalToGlobal(tempPoint);
- itemChosen := PopUpMenuSelect(fontPopUpRecord.menuHandle,
- tempPoint.v, tempPoint.h,
- fontPopUpRecord.chosenItem);
- temp := LoWord(itemChosen);
- IF temp <> 0 THEN
- BEGIN
- fontPopUpRecord.chosenItem := temp;
- GetItem(fontPopUpRecord.menuHandle, temp, tempString);
- ChangeCircleFont(@currentCircle, tempString);
- dialogChanged := TRUE;
- InvalRect(ourItemBox); { invalidate the font pop-up
- menu's item box }
- END;
- InvertRect(popUpTitleRect);
- END;
-
- sizePopUp:
- BEGIN
-
- { If we hit the size pop-up, adjust the size menu and track
- changes to the menu with PopUpMenuSelect. If the user picks
- a new size, update the type-in size editText field and the
- circle item. }
-
- GetDItem(theDialog, sizePopUp, ourItemType, ourItem,
- ourItemBox);
- GetFNum(currentCircle.circleFont, temp);
- AdjustSizeMenu(theDialog, sizePopUpRecord, sizeEditText, 0,
- temp);
- tempPoint := ourItemBox.topLeft; LocalToGlobal(tempPoint);
- itemChosen := PopUpMenuSelect(sizePopUpRecord.menuHandle,
- tempPoint.v, tempPoint.h,
- sizePopUpRecord.chosenItem);
- temp := LoWrd(itemChosen);
- IF (temp <> 0) THEN
- BEGIN
- sizePopUpRecord.chosenItem := temp;
- GetItem(sizePopUpRecord.menuHandle, temp, tempString);
- StringToNum(tempString, tempLong);
- GetDItem(theDialog, sizeEditText, ourItemType, ourItem,
- ourItemBox);
- SetIText(ourItem, tempString);
- SelIText(theDialog, sizeEditText, 0, 32767);
- ChangeCircleTxSize(@currentCircle, tempLong); { the size
- is still in this temporary variable }
- dialogChanged := TRUE;
- END;
- END;
-
- sizeEditText:
- BEGIN
-
- { If we got a hit in the size editText item, check the new
- number entered to see if it's in line or not. We look at
- the oldCircleHeight global variable to see the height of
- the original circle, and make sure the point size isn't
- taller than the circle height. If it is, Alert the user
- that the circles aren't that tall and set to the maximum
- value. If the size changed at all, update the circle. }
-
- GetDItem(theDialog, sizeEditText, ourItemType, ourItem,
- ourItemBox);
- GetIText(ourItem, tempString);
- StringToNum(tempString, tempLong);
- IF tempLong > oldCircleHeight THEN
- BEGIN
- tempLong := oldCircleHeight;
- NumToString(tempLong, maxPointString);
- tempLong := tempLong + 1;
- NumToString(tempLong, maxRectString);
- ParamText(maxPointString, maxRectString, '', '');
- AlertUser(rSizeTooBigAlert);
- tempLong := oldCircleHeight;
- NumToString(tempLong, tempString);
- SetIText(ourItem, tempString);
- SelIText(theDialog, sizeEditText, 32767, 32767);
- END;
- IF tempLong <> currentCircle.circleTxSize THEN
- BEGIN
- ChangeCircleTxSize(@currentCircle, tempLong);
- dialogChanged := TRUE;
- END;
- END;
-
- textEditText:
- BEGIN
-
- { If we get a hit in the circle text editText item, make
- sure the text has actually changed and, if it has, update
- the circle with the new text. }
-
- GetDItem(theDialog, textEditText, ourItemType, ourItem,
- ourItemBox);
- GetIText(ourItem, tempString);
- IF tempString <> currentCircle.circleText THEN
- BEGIN
- ChangeCircleText(@currentCircle, tempString);
- dialogChanged := TRUE;
- END;
- END;
- OTHERWISE; { prevents undefined case errors }
- END;
-
- IF dialogChanged THEN
- InvalidateCircle(@currentCircle); { redraw if we changed the circle }
-
- END; { SampleFilterProc }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: InitializeCircleDialog
- *
- * InitializeCircleDialog gets the dialog from a resource and sets all the
- * controls to reflect the current state of the circle, and of the system.
- * For example, there's no "Color..." button if Color QuickDraw isn't
- * available. (No sense being cruel to people.) It returns a pointer to
- * the new dialog.
- *
- ******************************************************************************)
-
- FUNCTION InitializeCircleDialog(circle: CircleRec): DialogPtr;
-
- VAR
- ourDialog: DialogPtr; { the dialog we create }
- ourItemType, { for Get/SetDItem }
- theFont: INTEGER; { our circle's font number }
- ourItem: Handle; { for Get/SetDItem }
- ourItemBox: Rect; { for Get/SetDItem }
- tempWidth: INTEGER; { temporary width for calculations }
-
- BEGIN
-
- ourDialog := GetNewDialog(circleDialogID, NIL, pointer( - 1));
-
- { The dialog is created invisibly, so now we can set it up how we please }
-
- IF ourDialog <> NIL THEN
- BEGIN
- IF NOT gHasColorQD THEN
- HideDItem(ourDialog, colorButton); { don't show the Color button
- if we can't use it }
-
- { create the font pop-up menu with AddResMenu }
-
- fontPopUpRecord.menuHandle := GetMenu(mFonts);
- AddResMenu(fontPopUpRecord.menuHandle, 'FONT');
- InsertMenu(fontPopUpRecord.menuHandle, - 1);
- fontPopUpRecord.chosenItem := 1;
-
- { Get the size pop-up menu from our resource fork }
-
- sizePopUpRecord.menuHandle := GetMenu(mSize);
- InsertMenu(sizePopUpRecord.menuHandle, - 1);
-
- { install our user item procedures }
-
- GetDItem(ourDialog, fontPopUp, ourItemType, ourItem, ourItemBox);
- CalcMenuSize(fontPopUpRecord.menuHandle);
- tempWidth := fontPopUpRecord.menuHandle^^.menuWidth + ourItemBox.left;
- IF tempWidth < ourItemBox.right THEN
- ourItemBox.right := tempWidth;
- SetDItem(ourDialog, fontPopUp, ourItemType, Handle(@DrawPopUpItem),
- ourItemBox);
-
- GetDItem(ourDialog, defaultUserItem, ourItemType, ourItem,
- ourItemBox);
- SetDItem(ourDialog, defaultUserItem, ourItemType,
- Handle(@DrawDefaultItem),ourItemBox);
-
- GetDItem(ourDialog, circleUserItem, ourItemType, ourItem,
- ourItemBox);
- SetDItem(ourDialog, circleUserItem, ourItemType,
- Handle(@DrawCircleItem), ourItemBox);
-
- currentCircle.circleRect := ourItemBox; { Handily retrieved from
- GetDItem recently }
-
- { We start with the first text item in the dialog selected, and
- that's the size text in this case }
-
- GetFNum(currentCircle.circleFont, theFont);
- AdjustSizeMenu(ourDialog, sizePopUpRecord, sizeEditText,
- currentCircle.circleTxSize, theFont);
-
- MakeDialogCurrent(ourDialog); { Make the dialog reflect
- currentCircle }
-
- ShowWindow(WindowPtr(ourDialog));
- END;
-
- InitializeCircleDialog := ourDialog;
-
- END; { InitializeCircleDialog }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * Public: DoCircleOptions
- *
- * DoCircleOptions presents a nice modal dialog to change a circle's attributes
- * and lets you watch while you do it. It returns TRUE if the user accepted
- * changes to the circle and FALSE otherwise.
- *
- * The filter procedure does a lot of the work, but this routine handles
- * closing down the dialog, twiddling checkboxes, changing the circle's
- * color and monitoring for changes in any of the items.
- *
- ******************************************************************************)
-
- FUNCTION DoCircleOptions(VAR circle: CircleRec): BOOLEAN;
-
- VAR
- theDialog: DialogPtr; { the dialog we're creating }
- itemHit: INTEGER; { the item the user hit }
- oldCircleRect: Rect; { the original circle rectangle }
- killDialog, { TRUE if it's time to dismiss
- the dialog }
- dialogChanged, { TRUE if something just changed
- in the dialog }
- dialogEverChanged: BOOLEAN; { TRUE if anything _ever_ changed
- in the dialog }
-
- BEGIN
- DoCircleOptions := FALSE; { by default, no changes }
- currentCircle := circle; { copy the circle to our global
- variable }
- oldCircleRect := circle.circleRect; { keep the old Rect }
- oldCircleHeight := circle.circleRect.bottom - circle.circleRect.top;
- { keep the old height in a global
- variable }
- theDialog := InitializeCircleDialog(currentCircle);
- { setup the dialog and user items }
- SetPort(GrafPtr(theDialog)); { set to the dialog }
- killDialog := FALSE; { not time to dismiss it }
- dialogEverChanged := FALSE; { hasn't changed yet }
-
- REPEAT
- dialogChanged := FALSE; { haven't changed this time through }
- ModalDialog(@SampleFilterProc, itemHit);
-
- CASE itemHit OF
-
- ok:
- BEGIN
-
- { save our changes in the original circle, kill the dialog
- and note whether there were any changes in the return
- value }
-
- circle := currentCircle;
- circle.circleRect := oldCircleRect;
- killDialog := TRUE;
- DoCircleOptions := dialogEverChanged;
- END;
-
- cancel:
-
- { don't save any changes, just dismiss the dialog }
-
- killDialog := TRUE;
-
- boldBox, italicBox, underlineBox, outlineBox, shadowBox,
- condensedBox, extendedBox, plainBox:
- BEGIN
-
- { Handle changes to style checkboxes here }
-
- TwiddleCheckBoxItem(theDialog, itemHit);
- CheckBoxItemsToStyle(currentCircle.circleFace, boldBox,
- theDialog, itemHit);
- SetItemEnable(theDialog, plainBox,
- NOT GetCheckBoxItemValue(theDialog, plainBox));
- dialogChanged := TRUE;
- END;
-
- colorButton:
- BEGIN
- ChangeCircleColor(@currentCircle); dialogChanged := TRUE;
- END;
-
- fontPopUp, fontTitle, sizePopUp, sizeEditText, textEditText:
- dialogEverChanged := TRUE;
-
- OTHERWISE; { prevents undefined case errors }
- END;
-
- IF dialogChanged THEN
- BEGIN
- dialogEverChanged := TRUE;
- InvalidateCircle(@currentCircle);
- END;
-
- UNTIL killDialog;
-
- DestroyCircleDialog; { deallocate our storage }
- DisposeDialog(theDialog); { and dispose of the dialog }
-
- END; { DoCircleOptions }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * private: PrefsFilterProc
- *
- * This filter procedure is passed to ModalDialog when conducting the
- * preferences dialog. It's not as complicated as the SampleFilterProc --
- * all the user can do besides OK and Cancel is change three editText items.
- * Here we only filter on what the event is. The code should look familiar
- * to those who've read SampleFilterProc. We pass update and activate events
- * for non-dialog windows to the main event handler, as before.
- *
- ******************************************************************************)
-
- FUNCTION PrefsFilterProc(theDialog: DialogPtr; VAR theEvent: EventRecord;
- VAR itemHit: INTEGER): BOOLEAN;
-
- VAR
- theFlags, { returned by ClassifyKey }
- theField: INTEGER; { which field is active }
-
- BEGIN
- PrefsFilterProc := FALSE; { we don't handle the event by default }
-
- CASE theEvent.what OF
-
- keyDown, autoKey:
- BEGIN
- theFlags := ClassifyKey(@theEvent);
- theField := DialogPeek(theDialog)^.editField + 1;
- IF (BAND(theFlags, kCancelKey) <> 0) THEN
- BEGIN
- itemHit := cancel;
- BlinkButtonItem(theDialog, cancel);
- PrefsFilterProc := TRUE;
- END
- ELSE IF (BAND(theFlags, kAcceptKey) <> 0) THEN
- BEGIN
- itemHit := ok;
- BlinkButtonItem(theDialog, ok);
- PrefsFilterProc := TRUE;
- END
- ELSE IF (theField = numCirclesEditText) OR (theField =
- rectSizeEditText) OR (theField =
- circleInsetEditText) THEN
- IF BAND(theFlags, kDigitKey + kCommandKey + kEditKey) =
- 0 THEN
- BEGIN
- PrefsFilterProc := TRUE;
- SysBeep(5); { beep to indicate there's a bad
- entry }
- END;
- END;
-
- updateEvt, activateEvt:
- IF DialogPtr(theEvent.message) <> theDialog THEN
- DoEvent(theEvent);
- OTHERWISE; { prevents undefined case errors }
- END;
- END; { PrefsFilterProc }
-
- {$S Dialogs}
- (******************************************************************************
- *
- * Public: DoEditPreferences
- *
- * DoEditPreferences conducts a dialog to change the preferences stored in
- * the global preferences record.
- *
- ******************************************************************************)
-
- PROCEDURE DoEditPreferences;
-
- VAR
- theDialog: DialogPtr; { the actual preferences dialog }
- ourItemType, { for Get/SetDItem }
- itemHit: INTEGER; { the item returned by ModalDialog }
- ourItem: Handle; { for Get/SetDItem }
- ourItemBox: Rect; { for Get/SetDItem }
- tempString, { temp. conversion of nums to strings }
- realMaxString: Str255; { string holding maximum inset value }
- tempInset, { temporary inset value }
- tempInsetMax, { maximum inset value }
- tempLong: LONGINT; { temporary four-byte storage }
- killDialog, { TRUE if time to dismiss dialog }
- acceptChanges: BOOLEAN; { TRUE if we should accept changes }
-
- BEGIN
- theDialog := GetNewDialog(prefsID, NIL, WindowPtr(-1));
- SetPort(GrafPtr(theDialog));
- killDialog := FALSE; { not ready to dismiss yet }
- acceptChanges := FALSE; { don't accept changes until told to }
-
- WITH gPrefsRecord DO
- BEGIN
-
- { Set the default value of our editText fields from the global
- preferences record, and select the first item's text }
-
- tempLong := maxNumCircles;
- NumToString(tempLong, tempString);
- GetDItem(theDialog, numCirclesEditText, ourItemType, ourItem,
- ourItemBox);
- SetIText(ourItem, tempString);
-
- tempLong := circleRectSize;
- NumToString(tempLong, tempString);
- GetDItem(theDialog, rectSizeEditText, ourItemType, ourItem,
- ourItemBox);
- SetIText(ourItem, tempString);
-
- tempLong := circleInsetSize;
- NumToString(tempLong, tempString);
- GetDItem(theDialog, circleInsetEditText, ourItemType, ourItem,
- ourItemBox);
- SetIText(ourItem, tempString);
-
- SelIText(theDialog, numCirclesEditText, 0, 32767);
- END;
-
- { Set the DrawDefaultItem procedure to frame our default Button }
-
- GetDItem(theDialog, prefsUserItem, ourItemType, ourItem, ourItemBox);
- SetDItem(theDialog, prefsUserItem, ourItemType, Handle(@DrawDefaultItem),
- ourItemBox);
-
- REPEAT
-
- ModalDialog(@PrefsFilterProc, itemHit);
- CASE itemHit OF
-
- ok:
- BEGIN
- { dismiss dialog and save changes }
- killDialog := TRUE;
- acceptChanges := TRUE;
- END;
-
- cancel:
- { just dismiss dialog }
- killDialog := TRUE;
-
- numCirclesEditText:
- BEGIN
-
- { Due to static storage limitation, we can't have more
- than ten circles, even though we ask people how many
- is too many. If they try to enter more than 10,
- we alert them that this is not possible and set the
- maximum of ten for them. }
-
- GetDItem(theDialog, numCirclesEditText, ourItemType,
- ourItem, ourItemBox);
- GetIText(ourItem, tempString);
- StringToNum(tempString, tempLong);
- IF (tempLong > 10) THEN
- BEGIN
- AlertUser(rOnlyTenCirclesID);
- NumToString(10, tempString);
- SetIText(ourItem, tempString);
- SelIText(theDialog, numCirclesEditText, 0, 32767);
- END;
- END;
-
- rectSizeEditText:
- BEGIN
-
- { We don't allow rectangle sizes bigger than 500 pixels,
- so Alert the users that this isn't kosher. }
-
- GetDItem(theDialog, rectSizeEditText, ourItemType, ourItem,
- ourItemBox);
- GetIText(ourItem, tempString);
- StringToNum(tempString, tempLong);
- IF tempLong > 500 THEN
- BEGIN
- AlertUser(rLessThan500Please);
- NumToString(500, tempString);
- SetIText(ourItem, tempString);
- SelIText(theDialog, rectSizeEditText, 0, 32767);
- END;
- END;
-
- circleInsetEditText:
- BEGIN
-
- { Get the size of the rectangles into tempLong }
-
- GetDItem(theDialog, rectSizeEditText, ourItemType, ourItem,
- ourItemBox);
- GetIText(ourItem, tempString);
- StringToNum(tempString, tempLong);
-
- { Get the inset value into tempInset }
-
- GetDItem(theDialog, circleInsetEditText, ourItemType,
- ourItem, ourItemBox);
- GetIText(ourItem, tempString);
- StringToNum(tempString, tempInset);
-
- { To prevent teeny tiny circles, the inset can't be bigger
- than 40% of the rectangle size. Since the inset is on
- each side, that would make the circle only 20% or less
- of the rectangle size, and that's probably small enough.
- Calculate the real maximum value and inform the user of
- the maximum value, resetting his choice as necessary. }
-
- tempInsetMax := ((tempLong DIV 2) - (tempLong DIV 10));
- IF tempInset > tempInsetMax THEN
- BEGIN
- NumToString(tempInsetMax, tempString);
- ParamText(tempString, '', '', '');
- AlertUser(rInsetTooMuch);
- SetIText(ourItem, tempString);
- SelIText(theDialog, circleInsetEditText, 0, 32767);
- END;
- END;
-
- OTHERWISE; { prevents undefined case errors }
- END;
-
- UNTIL killDialog;
-
- IF acceptChanges THEN
- BEGIN
- WITH gPrefsRecord DO
- BEGIN
-
- { Get all the values out of the dialog and set the global
- preferences record to reflect them }
-
- GetDItem(theDialog, numCirclesEditText, ourItemType,
- ourItem, ourItemBox);
- GetIText(ourItem, tempString);
- StringToNum(tempString, tempLong);
- IF ((tempLong >= 1) AND (tempLong <= 10)) THEN
- maxNumCircles := tempLong;
-
- GetDItem(theDialog, rectSizeEditText, ourItemType, ourItem,
- ourItemBox);
- GetIText(ourItem, tempString);
- StringToNum(tempString, tempLong);
- circleRectSize := tempLong;
-
- GetDItem(theDialog, circleInsetEditText, ourItemType,
- ourItem, ourItemBox);
- GetIText(ourItem, tempString);
- StringToNum(tempString, tempLong);
- circleInsetSize := tempLong;
-
- { The user could have set a legal inset value for a circle,
- but then gone and made the rectangle size so small that the
- inset value becomes illegal. If this happens, alert the
- user to the problem, notify the user that you're using
- the allowed maximum value and go on with things. }
-
- tempInsetMax := ((circleRectSize DIV 2) -
- (circleRectSize DIV 10));
- IF (circleInsetSize > tempInsetMax) THEN
- BEGIN
- NumToString(circleInsetSize, tempString);
- NumToString(tempInsetMax, realMaxString);
- ParamText(tempString, realMaxString, '', '');
- AlertUser(rInsetMustBeChanged);
- circleInsetSize := tempInsetMax;
- END;
-
- { write the preferences back to disk }
-
- PutPrefsToFile(gPrefsRecord, - 1);
-
- END;
- END;
-
- SetPort(theDialog);
- DisposeDialog(theDialog);
-
- END;
-